home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / hypercrd / xcmd / dxcmds34.sit / Dartmouth XCMD's 3.4.3 / card_15753.txt < prev    next >
Text File  |  1990-04-17  |  37KB  |  1,160 lines

  1. -- card: 15753 from stack: in.3
  2. -- bmap block id: 0
  3. -- flags: 4000
  4. -- background id: 3241
  5. -- name: ModalDialog
  6. ----- HyperTalk script -----
  7. on Install
  8.   get ChooseTargetStack()
  9.   InstallResource XFCN,ModalDialog,it
  10. end Install
  11.  
  12.  
  13. -- part 3 (field)
  14. -- low flags: 81
  15. -- high flags: 2007
  16. -- rect: left=12 top=26 right=298 bottom=491
  17. -- title width / last selected line: 0
  18. -- icon id / first selected line: 0 / 0
  19. -- text alignment: 0
  20. -- font id: 22
  21. -- text size: 10
  22. -- style flags: 0
  23. -- line height: 13
  24. -- part name: Source
  25.  
  26.  
  27. -- part 5 (button)
  28. -- low flags: 00
  29. -- high flags: A003
  30. -- rect: left=80 top=300 right=322 bottom=180
  31. -- title width / last selected line: 0
  32. -- icon id / first selected line: 0 / 0
  33. -- text alignment: 1
  34. -- font id: 0
  35. -- text size: 12
  36. -- style flags: 0
  37. -- line height: 16
  38. -- part name: Try It
  39. ----- HyperTalk script -----
  40. on mouseUp
  41.   DoSearch
  42.   -- the handler for the DoSearch message is in the script of
  43.   -- this stack
  44. end mouseUp
  45.  
  46.  
  47.  
  48. -- part 10 (button)
  49. -- low flags: 00
  50. -- high flags: A003
  51. -- rect: left=299 top=300 right=322 bottom=438
  52. -- title width / last selected line: 0
  53. -- icon id / first selected line: 0 / 0
  54. -- text alignment: 1
  55. -- font id: 0
  56. -- text size: 12
  57. -- style flags: 0
  58. -- line height: 16
  59. -- part name: Show Pascal Source
  60. ----- HyperTalk script -----
  61. on mouseUp
  62.   set the visible of card field 1 to not the visible of card field 1
  63.   if the visible of card field 1 is true then
  64.     set the name of me to "Hide Pascal Source"
  65.   else set the name of me to "Show Pascal Source"
  66. end mouseUp
  67.  
  68.  
  69.  
  70. -- part contents for background part 16
  71. ----- text -----
  72. MODALDIALOG XFCN version 1.0.3
  73. Kevin Calhoun
  74.  
  75. ModalDialog displays a dialog box created by any resource generator or editor, such as ResEdit.  It permits the user to interact with the dialog in the standard Macintosh fashion and, once the user dismisses the dialog, returns information about the contents of all the editable text items and the state of all the check boxes and radio buttons at the time the dialog was dismissed.
  76.  
  77. INVOKING MODALDIALOG
  78.  
  79. get ModalDialog("DLOGName",<containerName>,<dialogPositioning>,<noCancel>,<noWordWrap>)
  80.  
  81. returns 
  82.    if the user presses the default button:  a multi-lined expression, explained below,  
  83.    describing the contents of the dialog box
  84.  
  85.    if the user presses the cancel button:  "Cancel" 
  86.  
  87.    if an error occurs:  "Error " followed by an error code
  88.  
  89. WHAT YOU PASS TO MODALDIALOG
  90.  
  91. You tell ModalDialog which dialog to display by passing the name of its DLOG resource in the first parameter.  For example, ModalDialog("ask") brings up HyperCard's ask dialog.  You should enclose this name in quotation marks.
  92.  
  93. The rest of the parameters are optional.
  94.  
  95. The second parameter, containerName, is the name of a HyperTalk container.  Before calling ModalDialog, you can store a multi-lined expression in this container that will determine the following properties of the dialog:  the text of text items, the initial state of check boxes and radio buttons, the grouping of radio buttons, and the default and cancel buttons.  The container should include one line for each dialog item in the DITL resource--ModalDialog matches each dialog item with the corresponding line in the container.  If there is no second parameter, or if it is empty, then the dialog will appear in the default state:  the text items will contain the text specified by the DITL, check boxes and radio buttons will be turned off, all radio buttons will be grouped together, the default button will be the first button in the DITL, and the cancel button will be the second button in the DITL.  The next few paragraphs explain how to override this default behavior.
  96.  
  97. If the dialog item is a button control, ModalDialog looks in its corresponding line in containerName for two items:
  98.  
  99.    defaultOrCancel,Name
  100.  
  101. If defaultOrCancel is "Default", the button becomes the default button (the one that's pushed when the user presses the return or enter key) and the familiar bold outline will be drawn around it.  If defaultOrCancel is "Cancel", the button becomes the cancel button (the one that's pushed when the user presses the escape key, command-period, or command-Q).  If more than one button is designated the default button, the last of these in the list becomes the actual default button.  The same rule applies for multiple buttons designated the cancel button.  If Name is not empty, then the title of the button will be set to it.
  102.  
  103. If the dialog item is a check box, ModalDialog looks in its corresponding line in containerName for two items:
  104.  
  105.    onOrOff,Name
  106.  
  107. If onOrOff is "On", the check box will be checked when it first appears.  If Name is not empty, the title of the check box will be set to it.
  108.  
  109. If the dialog item is a radio button, ModalDialog looks in its corresponding line in containerName for three items:
  110.  
  111.    onOrOff,group,Name
  112.  
  113. If onOrOff is "On", the radio button will be on when it first appears.  Group is a number that tells ModalDialog which radio buttons should be turned off when the user turns the radio button on.  When the user clicks a radio button, ModalDialog does nothing if the radio button is already on; if it's off, every other radio button with the same group number is turned off before it's turned on.  If group is empty, the radio button is assigned to group number 0.  (Note:  ModalDialog doesn't check whether you turn more than one radio button on within the same group.  If you do this, the radio buttons in that group will not behave normally.)  If Name is not empty, the title of the radio button will be set to it.
  114.  
  115. If the dialog item is an editable text item, ModalDialog looks in its corresponding line in containerName for two items:
  116.  
  117.    text,select
  118.  
  119. If text is not empty, the text of the dialog item will be set to it.  If select is "Select", the text of the item will be selected.  If more than one text item is designated the selected item, the last of these in the list will actually be selected when the dialog appears.  If none of the dialog items is selected in this fashion, the first edit item in the list will be selected when the dialog appears.
  120.  
  121. If the dialog item is a static text item, ModalDialog will set the text of the dialog item to the line in containerName that corresponds to it, unless that line is empty.
  122.  
  123. If the dialog item is an icon item, a picture item, a user item, or a control defined by a resource template in a resource file, ModalDialog ignores the line in containerName that corresponds to it.
  124.  
  125. The third parameter, dialogPositioning, tells ModalDialog how to position the dialog on the screen, as follows.  
  126.  
  127. dialogPositioning            effect
  128. ---------------------           -------------------------------------------------------------------------    
  129. "cardOffset"                    coordinates in DLOG resource are treated as local to the card
  130. "cardCenter"                   the dialog is centered over the card window
  131. "screenCenter"                the dialog is centered on the main screen
  132.  
  133. In addition, each of these options may be preceded by an "h" or a "v", with the following effects:  "h" tells ModalDialog to alter only the horizontal positioning of the dialog, while "v" tells it to alter only the vertical positioning.  For example, "hScreenCenter" will cause the dialog to be centered horizontally on the screen while retaining the vertical positioning specified in the DLOG resource.  If there is no third parameter, or if it is something other than these options, the coordinates ModalDialog finds in the DLOG resource are treated as global coordinates and become the dialog's bounding rectangle.  
  134. (Note:  for compatibility with earlier versions, TRUE means the same thing as 
  135. "cardOffset".)
  136.  
  137. The fourth parameter, noCancel, tells ModalDialog whether or not there is a cancel item.  If noCancel is TRUE, the user cannot dismiss the dialog by pressing command-period, command-Q, or the escape key, or by pressing any button other than the default item.  If noCancel is not present, or if it is anything other than TRUE, then the cancel item is determined by the methods described above and the dialog can be cancelled.
  138.  
  139. The fifth parameter, noWordWrap, tells ModalDialog whether or not you want automatic word wrapping in edit text items.  If it is TRUE, there will be no word wrap.  If it is absent or anything other than TRUE, the words will wrap.
  140.  
  141. WHAT MODALDIALOG RETURNS
  142.  
  143. If the user dismisses the dialog by clicking the default item or by pressing return or enter, ModalDialog returns a multi-line expression, one line per item in the dialog item list, describing what the dialog contained when it was dismissed.
  144.  
  145. If the item is a check box or a radio button, the line corresponding to it will contain "off" if the button was off and "on" if the button was on.
  146.  
  147. If the item is an edit text item, the line corresponding to it will contain the text of the item.
  148.  
  149. If the item is any other type of dialog item, the line corresponding to it will be empty.
  150.  
  151. If the user dismisses the dialog by clicking the cancel item or by pressing command-period, command-Q, or the escape key, then ModalDialog returns "Cancel".
  152.  
  153. REVISION HISTORY
  154. March 15, 1989 -- 1.0 release.
  155. March 31, 1989 -- 1.0.1.  Sped up scanning of input container.  Container name should no longer be quoted.  Default group for radio buttons is now 0, not 1.
  156. April 3, 1989 -- 1.0.2.  Added pre-flight check for presence of DITL resource.  Added more options for dialog positioning.
  157. June 25, 1989 -- 1.0.3.  If user copies a selection from an edit text item in the dialog, the desk scrap will contain that text after the dialog is dismissed.
  158.  
  159. -- part contents for card part 3
  160. ----- text -----
  161. UNIT ModalDialogUnit;
  162.  
  163. { ModalDialog XCMD ┬⌐1989 by the Trustees of Dartmouth College }
  164. { Written by Kevin Calhoun }
  165.  
  166. { This source compatible with MPW Pascal 3.0 }
  167.  
  168. (*
  169. Pascal ModalDialog.p
  170. Link -m ENTRYPOINT Γêé
  171.      -o "YourFile" Γêé
  172.      -rt XFCN=13013 Γêé
  173.      -sn Main=ModalDialog Γêé
  174.      ModalDialog.p.o Γêé
  175.     "{Libraries}"interface.o Γêé
  176.     "{PLibraries}"Paslib.o Γêé
  177.     "{Libraries}"HyperXLib.o
  178. *)
  179.  
  180. {$R-}
  181.  
  182. INTERFACE
  183.   USES
  184.     Types,
  185.     Memory,
  186.     Resources,
  187.     Dialogs,
  188.     Scrap,
  189.     ToolUtils,
  190.     OSUtils,
  191.     Packages,
  192.     Errors,
  193.     HyperXCmd;
  194.  
  195.   PROCEDURE Entrypoint (paramPtr : XCmdPtr);
  196.  
  197. IMPLEMENTATION
  198.  
  199.   CONST
  200.     btnOn = 1;
  201.   TYPE
  202.     GlobalsHandle = ^GlobalsPtr;
  203.     GlobalsPtr = ^GlobalsRecord;
  204.  
  205.     GlobalsRecord = RECORD
  206.         dlogItems : INTEGER;
  207.         wasDown : BOOLEAN;
  208.         alteredScrap : BOOLEAN;
  209.         defaultItem : INTEGER;
  210.         cancelItem : INTEGER;
  211.         selectedItem : INTEGER;
  212.         editTextRgn : RgnHandle;
  213.         arrowCursor, iBeamCurs : Cursor;
  214.       END;
  215.  
  216.     WordHandle = ^WordPtr;
  217.     WordPtr = ^INTEGER;
  218.  
  219.   PROCEDURE DoModalDlog (paramPtr : XCmdPtr); FORWARD;
  220.  
  221.   PROCEDURE Entrypoint (paramPtr: XCMDPtr);
  222.   BEGIN
  223.     DoModalDlog(paramPtr);
  224.   END;
  225.  
  226.   FUNCTION GetScreenBitsBounds: Rect;
  227.   TYPE
  228.     LongwordPtr = ^LONGINT;
  229.     BitMapPtr = ^BitMap;
  230.   CONST
  231.     screenBitsOffset = -122;
  232.     CurrentA5 = $904;
  233.   VAR
  234.     screenBitsPtr : BitMapPtr;
  235.     myLongwordPtr : LongwordPtr;
  236.   BEGIN
  237.     myLongwordPtr := LongwordPtr(CurrentA5);
  238.     myLongwordPtr := LongwordPtr(myLongwordPtr^);
  239.     screenBitsPtr := BitMapPtr(myLongwordPtr^ + screenBitsOffset);
  240.     GetScreenBitsBounds := screenBitsPtr^.bounds;
  241.   END;
  242.   
  243.   FUNCTION GetArrowCursor : Cursor;
  244.   TYPE
  245.     LongwordPtr = ^LONGINT;
  246.   CONST
  247.     arrowOffset = -108;
  248.     CurrentA5 = $904;
  249.   VAR
  250.     arrowPtr : CursPtr;
  251.     myLongwordPtr : LongwordPtr;
  252.   BEGIN
  253.     myLongwordPtr := LongwordPtr(CurrentA5);
  254.     myLongwordPtr := LongwordPtr(myLongwordPtr^);
  255.     arrowPtr := CursPtr(myLongwordPtr^ + arrowOffset);
  256.     GetArrowCursor := arrowPtr^;
  257.   END;
  258.  
  259.   PROCEDURE DrawBoxAroundDefault (theWindow : WindowPtr; itemNo : INTEGER);
  260.     VAR
  261.       itemType : integer;
  262.       itemHdl : Handle;
  263.       itemBox : rect;
  264.       item : INTEGER;
  265.       g : GlobalsHandle;
  266.       ps : PenState;
  267.       savePort : GrafPtr;
  268.   BEGIN
  269.     { If you steal this routine, get rid of the next three lines }
  270.     { and figure out what the default item is some other way. }
  271.     { Unless, of course, you use a handle to "globals" in the refCon }
  272.     { field, just as I do. }
  273.     g := GlobalsHandle(GetWRefCon(theWindow));
  274.     item := g^^.defaultItem;
  275.     GetDItem(theWindow, item, itemType, itemHdl, itemBox);
  276.     IF itemType = ctrlItem + btnCtrl THEN
  277.       BEGIN
  278.       GetPort(savePort);
  279.       SetPort(theWindow);
  280.       GetPenState(ps);
  281.       PenSize(3, 3);
  282.       InsetRect(itemBox, -4, -4);
  283.       FrameRoundRect(itemBox, 16, 16);
  284.       SetPenState(ps);
  285.       SetPort(savePort);
  286.       END;
  287.   END;
  288.  
  289.   FUNCTION AddUserItem (d: DialogPtr; default: INTEGER) : OSErr;
  290.     TYPE
  291.       DItemPtr = ^dialogItem;
  292.       DItemHndl = ^dItemPtr;
  293.       DialogItem = RECORD
  294.         placeholder : handle;
  295.         displayRect : Rect;
  296.         typeAndDataLength : INTEGER;
  297.         END;
  298.     VAR
  299.       theUserItem : DItemHndl;
  300.       itemType : INTEGER;
  301.       itemHdl : Handle;
  302.       itemBox : Rect;
  303.       theItems : Handle;
  304.       err : OSErr;
  305.   BEGIN
  306.     err := noErr;
  307.     GetDItem(d, default, itemType, itemHdl, itemBox);
  308.     IF itemType = ctrlItem + btnCtrl THEN
  309.       BEGIN
  310.       InsetRect(itemBox, -4, -4);
  311.       theUserItem := DItemHndl(NewHandle(SIZEOF(DialogItem)));
  312.       err := MemError;
  313.       IF (theUserItem <> NIL) AND (err = noErr) THEN
  314.         BEGIN
  315.         MoveHHi(Handle(theUserItem));
  316.         HLock(Handle(theUserItem));
  317.         WITH theUserItem^^ DO
  318.           BEGIN
  319.           placeholder := Handle(@DrawBoxAroundDefault);
  320.           displayRect := itemBox;
  321.           typeAndDataLength := userItem * 256 + 0;
  322.           END;
  323.         theItems := DialogPeek(d)^.Items;
  324.         err := HandAndHand(Handle(theUserItem), theItems);
  325.         WordHandle(theItems)^^ := WordHandle(theItems)^^ + 1;
  326.         DisposHandle(Handle(theUserItem));
  327.         END;
  328.       END;
  329.     AddUserItem := err;
  330.   END;
  331.  
  332.   FUNCTION PtrToString (p: Ptr; size: byte): Str255;
  333.   TYPE
  334.     StrArray = PACKED ARRAY[0..255] of char;
  335.   VAR
  336.     s: Str255;
  337.   BEGIN
  338.     StrArray(s)[0] := CHR(size);
  339.     BlockMove(p, Ptr(ORD4(@s) + 1), size);
  340.     PtrToString := s;
  341.   END;
  342.  
  343.   FUNCTION GetNextLine(paramPtr: XCMDPtr; var scanPtr: Ptr;
  344.                    var line: Str255) : BOOLEAN;
  345.     VAR
  346.       tempPtr : Ptr;
  347.       temp : BOOLEAN;
  348.       stringLength : LONGINT;                
  349.   BEGIN
  350.     tempPtr := scanPtr;
  351.     ScanToReturn(paramPtr, scanPtr);
  352.     stringLength := ORD4(scanPtr)-ORD4(tempPtr);
  353.     line := PtrToString(tempPtr, stringLength);
  354.     GetNextLine := (scanPtr^ = 0);
  355.     { advance our pointer beyond the CR, for the next time we're called }
  356.     scanPtr := Ptr(ORD4(scanPtr)+1);
  357.   END;
  358.  
  359.   FUNCTION GetNextItem(sPtr: StringPtr; var index: INTEGER;
  360.                        var item: Str255) : BOOLEAN;
  361.     VAR
  362.       start: INTEGER;
  363.       sLength: INTEGER;
  364.   BEGIN
  365.     sLength := LENGTH(sPtr^);
  366.     start := index;
  367.     WHILE (sPtr^[index] <> ',') AND (index < sLength) DO
  368.       index := index+1;
  369.     IF index >= sLength THEN
  370.       BEGIN
  371.       GetNextItem := TRUE;
  372.       IF sPtr^[sLength] = ',' THEN index:=index-1;
  373.       item := COPY(sPtr^, start, (index-start+1));
  374.       index := sLength+1;
  375.       END
  376.     ELSE
  377.       BEGIN
  378.       GetNextItem := FALSE;
  379.       item := COPY(sPtr^, start, (index-start));
  380.       index := index+1;
  381.       END;
  382.   END;
  383.  
  384.   PROCEDURE SetButtonItem(item: INTEGER; c: ControlHandle; desc: Str255);
  385.     VAR
  386.       lastItem : BOOLEAN;
  387.       itemStr: Str255;
  388.       g: GlobalsHandle;
  389.       index: INTEGER;
  390.   BEGIN
  391.     index := 1;
  392.     lastItem := GetNextItem(@desc, index, itemStr);
  393.     g := GlobalsHandle(GetWRefCon(c^^.contrlOwner));
  394.     IF IUEqualString(itemStr, 'Default') = 0 THEN
  395.       g^^.defaultItem := item
  396.     ELSE IF IUEqualString(itemStr, 'Cancel') = 0 THEN
  397.       g^^.cancelItem := item;
  398.       
  399.     IF NOT lastItem THEN
  400.       BEGIN
  401.       lastItem := GetNextItem(@desc, index, itemStr);
  402.       IF LENGTH(itemStr) > 0 THEN SetCTitle(c, itemStr);
  403.       END;
  404.   END;
  405.  
  406.   PROCEDURE SetCheckBox(item: INTEGER; c: ControlHandle; desc: Str255);
  407.     VAR
  408.       lastItem: BOOLEAN;
  409.       itemStr: Str255;
  410.       index: INTEGER;
  411.   BEGIN
  412.     index := 1;
  413.     lastItem := GetNextItem(@desc, index, itemStr);
  414.     IF IUEqualString(itemStr, 'On') = 0 THEN
  415.       SetCtlValue(c, btnOn);
  416.       
  417.     IF NOT lastItem THEN
  418.       BEGIN
  419.       lastItem := GetNextItem(@desc, index, itemStr);
  420.       IF LENGTH(itemStr) > 0 THEN
  421.         SetCTitle(c, itemStr);
  422.       END;
  423.   END;
  424.  
  425.   PROCEDURE SetRadioButton(paramPtr: XCMDPtr;
  426.                 item: INTEGER; c: ControlHandle; desc: Str255);
  427.     VAR
  428.       lastItem : BOOLEAN;
  429.       itemStr: Str255;
  430.       group: INTEGER;
  431.       index: INTEGER;
  432.   BEGIN
  433.     index := 1;
  434.     lastItem := GetNextItem(@desc, index, itemStr);
  435.     IF IUEqualString(itemStr, 'On') = 0 THEN
  436.       SetCtlValue(c, btnOn);
  437.  
  438.     IF NOT lastItem THEN
  439.       BEGIN
  440.       lastItem := GetNextItem(@desc, index, itemStr);
  441.       IF LENGTH(itemStr) > 0 THEN
  442.         BEGIN
  443.         group := StrToNum(paramPtr, itemStr);
  444.         SetCRefCon(c, group);
  445.         END;
  446.   
  447.       IF NOT lastItem THEN
  448.         BEGIN
  449.         lastItem := GetNextItem(@desc, index, itemStr);
  450.         IF LENGTH(itemStr) > 0 THEN SetCTitle(c, itemStr);
  451.         END;
  452.       END;
  453.     
  454.   END;
  455.  
  456.   PROCEDURE SetEditItem(d: DialogPtr; item: INTEGER;
  457.                         h: Handle; desc: Str255);
  458.     VAR
  459.       lastItem : BOOLEAN;
  460.       itemStr: Str255;
  461.       g: GlobalsHandle;
  462.       index: INTEGER;
  463.   BEGIN
  464.     index := 1;
  465.     lastItem := GetNextItem(@desc, index, itemStr);
  466.     IF LENGTH(itemStr) > 0 THEN SetIText(h, itemStr);
  467.       
  468.     IF NOT lastItem THEN
  469.       BEGIN
  470.       lastItem := GetNextItem(@desc, index, itemStr);
  471.       IF IUEqualString(itemStr, 'Select') = 0 THEN
  472.         BEGIN
  473.         g := GlobalsHandle(GetWRefCon(d));
  474.         g^^.selectedItem := item;
  475.         END;
  476.       END;
  477.   END;
  478.  
  479.   PROCEDURE SetDialogItems(paramPtr: XCMDPtr;
  480.     d: DialogPtr; dlogItems: INTEGER; inContainer: Handle);
  481.     VAR
  482.       hs: SignedByte;
  483.       scanPtr: Ptr;
  484.       i : INTEGER;
  485.       str : Str255;
  486.       lastLine : BOOLEAN;
  487.       itemType : integer;
  488.       itemHdl : Handle;
  489.       itemBox : rect;
  490.       
  491.   BEGIN
  492.     hs := HGetState(inContainer);
  493.     HLock(inContainer);
  494.     scanPtr := inContainer^;
  495.     FOR i := 1 to dlogItems DO
  496.       BEGIN
  497.       GetDItem(d, i, itemType, itemHdl, itemBox);
  498.       lastLine := GetNextLine(paramPtr, scanPtr, str);
  499.       CASE itemType MOD itemDisable OF
  500.         ctrlItem + btnCtrl:
  501.           SetButtonItem(i, ControlHandle(itemHdl), str);
  502.         ctrlItem + chkCtrl:
  503.           SetCheckBox(i, ControlHandle(itemHdl), str);
  504.         ctrlItem + radCtrl:
  505.           SetRadioButton(paramPtr, i, ControlHandle(itemHdl), str);
  506.         statText:
  507.           IF LENGTH(str) > 0 THEN SetIText(itemHdl, str);
  508.         editText:
  509.           SetEditItem(d, i, itemHdl, str);
  510.         END;  { case itemType MOD itemDisable }  
  511.       IF lastLine then Leave;
  512.       END;  { for i := 1 to dlogItems }
  513.     HSetState(inContainer, hs);
  514.   END;
  515.  
  516.   FUNCTION ItemCount (theDialogPtr : DialogPtr) : integer;
  517.   BEGIN
  518.     ItemCount := WordHandle(DialogPeek(theDialogPtr)^.items)^^ + 1;
  519.   END;
  520.  
  521.   FUNCTION GetLocOfCardWindow (cardWindow : WindowPtr) : Point;
  522.     VAR
  523.       savePort : GrafPtr;
  524.       pt: Point;
  525.   BEGIN
  526.     GetPort(savePort);
  527.     SetPort(cardWindow);
  528.     WITH cardWindow^.portRect DO SetPt(pt,left,top);
  529.     LocalToGlobal(pt);
  530.     SetPort(savePort);
  531.     GetLocOfCardWindow := pt;
  532.   END;
  533.  
  534.   PROCEDURE MoveDialogRelativeToWindow (cardWindow: WindowPtr;
  535.                   doH, doV: BOOLEAN; 
  536.                   theDialogTHndl : DialogTHndl);
  537.     VAR
  538.       tempRect : Rect;
  539.       cardLoc : Point;
  540.   BEGIN
  541.     tempRect := theDialogTHndl^^.boundsRect;
  542.     cardLoc := GetLocOfCardWindow(cardWindow);
  543.     WITH cardLoc DO
  544.       BEGIN
  545.           {offset our DLOG rect according to loc of card window }
  546.       IF NOT doH THEN h := 0;
  547.       IF NOT doV THEN v := 0;
  548.       OffSetRect(tempRect, h, v);
  549.       END;
  550.     theDialogTHndl^^.boundsRect := tempRect; { set DLOG boundsRect}
  551.   END;
  552.  
  553.   PROCEDURE CenterRect(VAR r: Rect; inRect: Rect; doH, doV: BOOLEAN);
  554.     VAR
  555.       hSize, vSize: INTEGER;
  556.       hCoord, vCoord: INTEGER;
  557.   BEGIN
  558.     WITH r DO
  559.       BEGIN
  560.       hCoord := left;
  561.       vCoord := top;
  562.       hSize := right-left;
  563.       vSize := bottom-top;
  564.       END;
  565.     WITH inRect DO
  566.       BEGIN
  567.       IF doH THEN hCoord := (right-left - hSize) DIV 2 + left;
  568.       IF doV THEN vCoord := (bottom-top - vSize) DIV 2 + top;
  569.       END;
  570.     SetRect(r, hCoord, vCoord, hCoord+hSize, vCoord+vSize);
  571.   END;
  572.  
  573.   PROCEDURE CenterDialogOverWindow(cardWindow: WindowPtr;
  574.                                    doH, doV: BOOLEAN;
  575.                                    theDialogTHndl: DialogTHndl);
  576.     VAR
  577.       cardLoc : Point;
  578.       windowRect: Rect;
  579.       dlogRect: Rect;
  580.   BEGIN
  581.     cardLoc := GetLocOfCardWindow(cardWindow);
  582.     windowRect := cardWindow^.portRect;
  583.     WITH windowRect DO
  584.       OffsetRect(windowRect, -left, -top);
  585.     WITH cardLoc DO
  586.       OffsetRect(windowRect, h, v);
  587.     dlogRect := theDialogTHndl^^.boundsRect;
  588.     CenterRect(dlogRect, windowRect, doH, doV);
  589.     theDialogTHndl^^.boundsRect := dlogRect;
  590.   END;
  591.  
  592.   PROCEDURE CenterDialogOverScreen(doH, doV: BOOLEAN;
  593.                                    theDialogTHndl: DialogTHndl);
  594.     VAR
  595.       screenRect: Rect;
  596.       dlogRect: Rect;
  597.   BEGIN
  598.     dlogRect := theDialogTHndl^^.boundsRect;
  599.     screenRect := GetScreenBitsBounds;
  600.     CenterRect(dlogRect, screenRect, doH, doV);
  601.     theDialogTHndl^^.boundsRect := dlogRect;
  602.   END;
  603.  
  604.   FUNCTION SetUpGlobals (theDialog : DialogPtr) : OSErr;
  605.     LABEL
  606.       99;
  607.     VAR
  608.       err : OSErr;
  609.       numItems, i : INTEGER;
  610.       g : GlobalsHandle;
  611.       tempRgn : RgnHandle;
  612.       itemType : INTEGER;
  613.       ItemHdl : Handle;
  614.       itemBox : rect;
  615.       iBeam : CursHandle;
  616.       gotDefault, gotCancel, gotSelectedItem: BOOLEAN;
  617.   BEGIN
  618.     err := noErr;
  619.     g := GlobalsHandle(NewHandle(SizeOf(GlobalsRecord)));
  620.     err := MemError;
  621.     IF (err <> noErr) or (g = NIL) then GOTO 99;
  622.  
  623.     numItems := ItemCount(theDialog);
  624.  
  625.     WITH g^^ DO
  626.       BEGIN
  627.         dlogItems := numItems;
  628.         wasDown := FALSE;
  629.         alteredScrap := FALSE;
  630.       END;
  631.  
  632.     gotDefault := FALSE;
  633.     gotCancel := FALSE;
  634.     gotSelectedItem := FALSE;
  635.     
  636.     tempRgn := NewRgn;
  637.     OpenRgn;
  638.     FOR i := 1 TO numItems DO
  639.       BEGIN
  640.         GetDItem(theDialog, i, itemType, itemHdl, itemBox);
  641.         CASE itemType OF
  642.           editText, editText+itemDisable:
  643.             BEGIN
  644.             FrameRect(itemBox);
  645.             IF not gotSelectedItem THEN
  646.               BEGIN
  647.               g^^.selectedItem := i;
  648.               gotSelectedItem := TRUE;
  649.               END;
  650.             END;
  651.           ctrlItem + btnCtrl:
  652.             IF not gotDefault THEN
  653.               BEGIN
  654.               g^^.defaultItem := i;
  655.               gotDefault := TRUE;
  656.               END
  657.             ELSE IF not gotCancel THEN
  658.               BEGIN
  659.               g^^.cancelItem := i;
  660.               gotCancel := TRUE;
  661.               END;
  662.           END;
  663.       END;
  664.     CloseRgn(tempRgn);
  665.     err := MemError;
  666.     IF err <> noErr THEN
  667.       BEGIN
  668.       DisposHandle(Handle(g));
  669.       GOTO 99;
  670.       END;
  671.  
  672.     IF not gotDefault THEN g^^.defaultItem := OK;
  673.     IF not gotCancel THEN g^^.cancelItem := Cancel;
  674.     IF not gotSelectedItem THEN g^^.selectedItem := 0;
  675.     g^^.editTextRgn := tempRgn;
  676.  
  677.     iBeam := GetCursor(iBeamCursor);
  678.     g^^.iBeamCurs := iBeam^^;
  679.     g^^.arrowCursor := GetArrowCursor;
  680.  
  681.     SetWRefCon(theDialog,LONGINT(g));
  682.     
  683.     99: SetUpGlobals := err;
  684.   END;
  685.  
  686.   PROCEDURE DisposeGlobals (theDialog : DialogPtr);
  687.     VAR
  688.       g : GlobalsHandle;
  689.       rgn : RgnHandle;
  690.   BEGIN
  691.     g := GlobalsHandle(GetWRefCon(theDialog));
  692.     rgn := g^^.editTextRgn;
  693.     DisposeRgn(rgn);
  694.     DisposHandle(Handle(g));
  695.   END;
  696.  
  697.   FUNCTION TheFilter (theDialog : DialogPtr;
  698.                   VAR theEvent : EventRecord;
  699.                   VAR itemHit : integer) : boolean;
  700.  
  701.     VAR
  702.       mouseLoc : Point;
  703.       theItem : INTEGER;
  704.       numItems : INTEGER;
  705.       g : GlobalsHandle;
  706.       curs : Cursor;
  707.       theChar : INTEGER;
  708.       
  709.     FUNCTION SelectionNotEmpty(dlg: DialogPtr): BOOLEAN;
  710.     VAR
  711.       te: TEHandle;
  712.     BEGIN
  713.       SelectionNotEmpty := FALSE;
  714.       IF DialogPeek(dlg)^.editField > -1 THEN
  715.         WITH DialogPeek(dlg)^.textH^^ DO
  716.           SelectionNotEmpty := selEnd > selStart;
  717.     END;
  718.  
  719.     PROCEDURE PushButton (itemNo : INTEGER);
  720.       VAR
  721.         itemType : INTEGER;
  722.         itemHandle : Handle;
  723.         itemBox : Rect;
  724.         finalTicks : longint;
  725.     BEGIN
  726.       GetDItem(theDialog, itemNo, itemType, itemHandle, itemBox);
  727.       IF itemType = ctrlItem + btnCtrl THEN
  728.         BEGIN
  729.         HiliteControl(ControlHandle(itemHandle), btnOn);
  730.         Delay(3, finalTicks);
  731.         HiliteControl(ControlHandle(itemHandle), 0);
  732.         END;
  733.     END;
  734.  
  735.     PROCEDURE PrevEditField(dlg: DialogPtr);
  736.     VAR
  737.       numItems: INTEGER;
  738.       theEditItem: INTEGER;
  739.       itemType: INTEGER;
  740.       itemHandle: Handle;
  741.       itemBox: Rect;
  742.     BEGIN
  743.       numItems := ItemCount(dlg);
  744.         IF numItems > 0 THEN
  745.           BEGIN
  746.           theEditItem := DialogPeek(dlg)^.editField + 1;
  747.           if theEditItem > 0 then
  748.             BEGIN
  749.             REPEAT
  750.               theEditItem := (theEditItem + numItems - 2) MOD numItems + 1;
  751.               GetDItem(dlg, theEditItem, itemType, itemHandle, itemBox);
  752.             UNTIL (itemType mod itemDisable = editText);
  753.             SelIText(dlg, theEditItem, 0, 32767);
  754.             END;
  755.           END;
  756.     END;
  757.   
  758.   BEGIN
  759.     g := GlobalsHandle(GetWRefCon(theDialog));
  760.  
  761.     itemHit := 0;
  762.     TheFilter := false;
  763.  
  764.     numItems := g^^.dlogItems;
  765.     IF g^^.wasDown AND NOT StillDown THEN
  766.       BEGIN
  767.       ObscureCursor;
  768.       g^^.wasDown := false;
  769.       END;
  770.     mouseLoc := theEvent.where;
  771.     GlobalToLocal(mouseLoc);
  772.  
  773.     CASE theEvent.what OF
  774.       nullEvent,updateEvt : 
  775.         BEGIN
  776.         IF PtInRgn(mouseLoc, g^^.editTextRgn) THEN
  777.           curs := g^^.iBeamCurs
  778.         ELSE
  779.           curs := g^^.arrowCursor;
  780.         SetCursor(curs);
  781.         END;
  782.  
  783.       mouseDown : 
  784.         WITH g^^ DO
  785.           IF PtInRgn(mouseLoc, editTextRgn) THEN
  786.             wasDown := true;
  787.  
  788.       keyDown, autoKey : 
  789.         BEGIN
  790.           theChar := BitAnd(theEvent.message, charCodeMask);
  791.           CASE theChar OF
  792.             $2E, $71, $51: { command-., -q, or -Q }
  793.               BEGIN
  794.               IF BitAnd(theEvent.modifiers, cmdKey) <> 0 THEN
  795.                 BEGIN
  796.                 theItem := g^^.cancelItem;
  797.                 IF theItem > 0 THEN
  798.                   BEGIN
  799.                   PushButton(theItem);
  800.                   itemHit := theItem;
  801.                   TheFilter := TRUE;
  802.                   END;
  803.                 END;
  804.               END;
  805.             $78,$58:  { x, X }
  806.               IF BitAnd(theEvent.modifiers, cmdKey) <> 0 THEN
  807.                 BEGIN
  808.                 g^^.alteredScrap := g^^.alteredScrap OR SelectionNotEmpty(theDialog);
  809.                 TheFilter := TRUE;
  810.                 DlgCut(theDialog);
  811.                 END;
  812.             $63, $43:  { c, C }
  813.               IF BitAnd(theEvent.modifiers, cmdKey) <> 0 THEN
  814.                 BEGIN
  815.                 g^^.alteredScrap := g^^.alteredScrap OR SelectionNotEmpty(theDialog);
  816.                 TheFilter := TRUE;
  817.                 DlgCopy(theDialog);
  818.                 END;
  819.             $76, $56:  { v, V }
  820.               IF BitAnd(theEvent.modifiers, cmdKey) <> 0 THEN
  821.                 BEGIN
  822.                 TheFilter := TRUE;
  823.                 DlgPaste(theDialog);
  824.                 END;
  825.             $09: { tab key }
  826.               IF BitAnd(theEvent.modifiers, shiftKey) <> 0 THEN
  827.                 BEGIN
  828.                 TheFilter := TRUE;
  829.                 PrevEditField(theDialog);
  830.                 END;
  831.             $0D, $03: { Return or Enter }
  832.               BEGIN
  833.               theItem := g^^.defaultItem;
  834.               IF theItem > 0 THEN
  835.                 BEGIN
  836.                 PushButton(theItem);
  837.                 TheFilter := true;
  838.                 itemHit := theItem;
  839.                 END;
  840.               END;
  841.             $1B : { escape key }
  842.               BEGIN
  843.                 theItem := g^^.cancelItem;
  844.                 IF theItem > 0 THEN
  845.                   BEGIN
  846.                   PushButton(theItem);
  847.                   itemHit := theItem;
  848.                   TheFilter := TRUE;
  849.                   END;
  850.               END;
  851.             OTHERWISE
  852.               ObscureCursor;
  853.           END;  { case theChar }
  854.         END;    { keyDown }
  855.     END;  {case theEvent.what}
  856.   END; {function TheFilter}
  857.  
  858.   PROCEDURE DoCheckBox(c: ControlHandle);
  859.     VAR
  860.       controlValue : INTEGER;
  861.   BEGIN
  862.     controlValue := GetCtlValue(c);
  863.     controlValue := (controlValue + 1) MOD 2;
  864.     SetCtlValue(c, controlValue);
  865.   END;
  866.  
  867.   PROCEDURE DoRadioButtons(d: DialogPtr; item: INTEGER; c: ControlHandle);
  868.     VAR
  869.       controlValue : INTEGER;
  870.       group : INTEGER;
  871.       numItems : INTEGER;
  872.       i : INTEGER;
  873.       itemType : INTEGER;
  874.       itemHdl : Handle;
  875.       itemBox : Rect;
  876.   BEGIN
  877.     controlValue := GetCtlValue(c);
  878.     IF controlValue = 0 THEN
  879.       BEGIN
  880.       group := LoWord(GetCRefCon(c));
  881.       numItems := ItemCount(d);
  882.       FOR i := 1 to numItems DO
  883.         BEGIN
  884.         GetDItem(d, i, itemType, itemHdl, itemBox);
  885.         IF itemType = ctrlItem + radCtrl THEN
  886.           BEGIN
  887.           IF LoWord(GetCRefCon(ControlHandle(itemHdl))) = group THEN
  888.             SetCtlValue(ControlHandle(itemHdl), 0);
  889.           END;
  890.         END;
  891.       SetCtlValue(c, 1);
  892.       END;
  893.   END;
  894.  
  895.   FUNCTION AppendString (h: Handle; str: Str255): OSErr;
  896.   BEGIN
  897.     AppendString := PtrAndHand(POINTER(ORD4(@str)+1), h, LENGTH(str));
  898.   END;
  899.  
  900.   FUNCTION SpewOutResults(paramPtr: XCMDPtr; d: DialogPtr;
  901.               numItems: INTEGER; var h: Handle): OSErr;
  902.     LABEL
  903.       99;
  904.     VAR
  905.       err: OSErr;
  906.       str: Str255;
  907.       i: INTEGER;
  908.       itemType: INTEGER;
  909.       itemHdl: Handle;
  910.       itemBox: Rect;
  911.       return: String[1];
  912.       controlValue: INTEGER;
  913.       zeroPtr: Ptr;
  914.       
  915.     PROCEDURE SetReturnValue;
  916.     BEGIN
  917.       SpewOutResults := err;
  918.     END;
  919.       
  920.     PROCEDURE GetOut;
  921.     BEGIN
  922.       DisposHandle(h);
  923.       SetReturnValue;
  924.       EXIT(SpewOutResults);
  925.     END;
  926.     
  927.   BEGIN
  928.     err := noErr;
  929.     return := ' ';
  930.     return[1] := CHR($0D);
  931.     FOR i := 1 to numItems DO
  932.       BEGIN
  933.       GetDItem(d, i, itemType, itemHdl, itemBox);
  934.       CASE itemType MOD itemDisable OF
  935.         ctrlItem + chkCtrl, ctrlItem + radCtrl:
  936.           BEGIN
  937.           controlValue := GetCtlValue(ControlHandle(itemHdl));
  938.           IF controlValue = btnOn THEN str := CONCAT('on', return)
  939.           ELSE str := CONCAT('off', return);
  940.           err := AppendString(h, str);
  941.           IF err <> noErr THEN GetOut;
  942.           END;
  943.         editText:
  944.           BEGIN
  945.           GetIText(itemHdl, str);
  946.           str := CONCAT(str, return);
  947.           err := AppendString(h, str);
  948.           IF err <> noErr THEN GetOut;
  949.           END;
  950.         OTHERWISE
  951.           BEGIN
  952.           err := AppendString(h, return);
  953.           IF err <> noErr THEN GetOut;
  954.           END;
  955.         END;
  956.       END;
  957.     HLock(h);
  958.     zeroPtr := POINTER(ORD4(h^)+GetHandleSize(h)-1);
  959.     zeroPtr^ := 0;
  960.     HUnlock(h);
  961.     99: SetReturnValue;
  962.   END;
  963.  
  964.   PROCEDURE DoModalDlog (paramPtr : XCmdPtr);
  965.     LABEL
  966.       98, 99;
  967.     CONST
  968.       noWrap = -1;
  969.     VAR
  970.       dlogName : Str255;
  971.       inContainer : Handle;
  972.       str : Str255;
  973. {Resource related variables}
  974.       theResource, theDITL : Handle;
  975.       theId, ditlID : INTEGER;
  976.       theType : ResType;
  977. {Dialog related variables}
  978.       numItems : INTEGER;
  979.       myDialogTHndl : DialogTHndl;
  980.       myDialogPtr : DialogPtr;
  981.       dlogRect : Rect;
  982. {Dialog item related variables}
  983.       itemType : INTEGER;
  984.       ItemHdl : Handle;
  985.       itemBox : rect;
  986.       i, itemHit, def : INTEGER;
  987.       g : GlobalsHandle;
  988.       h : Handle;
  989.       movedIt : BOOLEAN;
  990.       hOrV : Char;
  991.       doH, doV: BOOLEAN;
  992.       cardWindow: WindowPtr;
  993.       scrapErr: LONGINT;
  994.       err : OSErr;
  995.  
  996.     PROCEDURE PassReturnValue (errMsg : Str255); { set theResult }
  997.     BEGIN
  998.       paramPtr^.returnValue := PasToZero(paramPtr, errMsg);
  999.     END;
  1000.  
  1001.   BEGIN
  1002.     err := noErr;
  1003.     IF paramPtr^.paramCount = 0 THEN
  1004.       BEGIN
  1005.       PassReturnValue('ModalDialog XFCN 1.0.3, 25 June 1989, ┬⌐1989 Dartmouth College');
  1006.       GOTO 99;
  1007.       END;
  1008.     
  1009.     GetPort(GrafPtr(cardWindow));  { get card window WindowPtr }
  1010.     
  1011.     ZeroToPas(paramPtr, paramPtr^.params[1]^, dlogName);
  1012.     IF LENGTH(dlogName) = 0 THEN GOTO 99;
  1013.     theResource := GetNamedResource('DLOG', dlogName);
  1014.     err := ResError;
  1015.     IF (theResource = NIL) OR (err <> noErr) THEN GOTO 99;
  1016.     
  1017.     IF paramPtr^.paramCount > 1 THEN inContainer := paramPtr^.params[2]
  1018.     ELSE inContainer := NIL;
  1019.     
  1020.     HNoPurge(theResource);
  1021.     GetResInfo(theResource, theID, theType, dlogName);
  1022.     err := ResError;
  1023.     IF err <> noErr THEN GOTO 99;
  1024.  
  1025.     myDialogTHndl := DialogTHndl(theResource);
  1026.     ditlID := myDialogTHndl^^.itemsID;
  1027.     theDITL := GetResource('DITL',ditlID);
  1028.     IF theDITL = NIL THEN
  1029.       BEGIN
  1030.       err := resNotFound;
  1031.       GOTO 99;
  1032.       END;
  1033.     
  1034.     movedIt := FALSE;
  1035.     myDialogTHndl^^.visible := FALSE;
  1036.     IF paramPtr^.paramCount > 2 THEN
  1037.       BEGIN
  1038.       dlogRect := myDialogTHndl^^.boundsRect;
  1039.       ZeroToPas(paramPtr, paramPtr^.params[3]^, str);
  1040.       hOrV := str[1];
  1041.       doH := TRUE;
  1042.       doV := TRUE;
  1043.       CASE hOrV OF
  1044.         'h','H': 
  1045.           BEGIN
  1046.           doV := FALSE;
  1047.           DELETE(str, 1, 1);
  1048.           END;
  1049.         'v','V':
  1050.           BEGIN
  1051.           doH := FALSE;
  1052.           DELETE(str, 1, 1);
  1053.           END;
  1054.         END;
  1055.       IF (IUEqualString(str, 'true')=0) OR (IUEqualString(str, 'cardOffset')=0) THEN
  1056.         BEGIN
  1057.         movedIt  := TRUE;
  1058.         MoveDialogRelativeToWindow(cardWindow, doH, doV, myDialogTHndl);
  1059.         END
  1060.       ELSE IF IUEqualString(str, 'cardCenter') = 0 THEN
  1061.         BEGIN
  1062.         movedIt  := TRUE;
  1063.         CenterDialogOverWindow(cardWindow, doH, doV, myDialogTHndl);
  1064.         END
  1065.       ELSE IF IUEqualString(str, 'screenCenter') = 0 THEN
  1066.         BEGIN
  1067.         movedIt  := TRUE;
  1068.         CenterDialogOverScreen(doH, doV, myDialogTHndl);
  1069.         END;
  1070.       END;
  1071.     
  1072.     myDialogPtr := GetNewDialog(theID, NIL, POINTER(-1));
  1073.     numItems := ItemCount(myDialogPtr);
  1074.  
  1075.     err := SetUpGlobals(myDialogPtr);
  1076.     IF err <> noErr THEN GOTO 98;
  1077.     
  1078.     IF paramPtr^.paramCount > 4 THEN
  1079.       BEGIN
  1080.       ZeroToPas(paramPtr, paramPtr^.params[5]^, str);
  1081.       IF StrToBool(paramPtr, str) THEN
  1082.         DialogPeek(myDialogPtr)^.textH^^.crOnly := noWrap;
  1083.             { turn off word wrap }
  1084.       END;
  1085.  
  1086.     IF inContainer <> NIL THEN
  1087.       SetDialogItems(paramPtr, myDialogPtr, numItems, inContainer);
  1088.       
  1089.     g := GlobalsHandle(GetWRefCon(myDialogPtr));
  1090.     def := g^^.defaultItem;
  1091.     
  1092.  
  1093.     err := AddUserItem(myDialogPtr, def);
  1094.     IF err <> noErr THEN
  1095.       BEGIN
  1096.       DisposeGlobals(myDialogPtr);
  1097.       GOTO 98;
  1098.       END;
  1099.       
  1100.     IF g^^.selectedItem > 0 THEN
  1101.       SelIText(myDialogPtr,g^^.selectedItem,0,32767);
  1102.       
  1103.     IF paramPtr^.paramCount > 3 THEN
  1104.       BEGIN
  1105.       ZeroToPas(paramPtr, paramPtr^.params[4]^, str);
  1106.       IF StrToBool(paramPtr, str) THEN
  1107.         g^^.cancelItem := 0;
  1108.       END;
  1109.  
  1110.     ShowWindow(myDialogPtr); { make DLOG visible }
  1111.     BringToFront(myDialogPtr);
  1112.     SetPort(myDialogPtr);
  1113.     InitCursor;
  1114.  
  1115.     REPEAT
  1116.       ModalDialog(@TheFilter, itemHit);
  1117.       GetDItem(myDialogPtr, itemHit, itemType, itemHdl, itemBox);
  1118.       CASE itemType OF
  1119.         ctrlItem + chkCtrl:
  1120.           DoCheckBox(ControlHandle(itemHdl));
  1121.         ctrlItem + radCtrl:
  1122.           DoRadioButtons(myDialogPtr, itemHit, ControlHandle(itemHdl));
  1123.         END;
  1124.     UNTIL (itemHit = def) OR (itemHit = g^^.cancelItem);
  1125.  
  1126.     IF g^^.alteredScrap THEN
  1127.       BEGIN
  1128.       scrapErr := ZeroScrap;
  1129.       scrapErr := TEToScrap;
  1130.       END;
  1131.     DisposeGlobals(myDialogPtr);
  1132.  
  1133.     IF itemHit = def THEN
  1134.       BEGIN
  1135.       h := NewHandle(0);
  1136.       err := MemError;
  1137.       IF err <> noErr THEN GOTO 98;
  1138.       
  1139.       err := SpewOutResults(paramPtr, myDialogPtr, numItems, h);
  1140.       IF err <> noErr THEN GOTO 98;
  1141.   
  1142.       paramPtr^.returnValue := h;
  1143.       END
  1144.     ELSE PassReturnValue('Cancel');
  1145.       
  1146. {set rect of DLOG to original rectangle}
  1147.     98:
  1148.     IF movedIt THEN
  1149.       myDialogTHndl^^.boundsRect := dlogRect; { reset DLOG boundsRect}
  1150.     HPurge(theResource);
  1151.     DisposDialog(myDialogPtr);
  1152.  
  1153.     99: IF err <> noErr THEN
  1154.       BEGIN
  1155.       NumToStr(paramPtr, err, str);
  1156.       PassReturnValue(CONCAT('Error ', str));
  1157.       END;
  1158.   END; {procedure DoModalDlog}
  1159.  
  1160. END.